#include "StdAfx.h"
#include "TinyTCPIF.h"
#include "TinyVoiceCardServerDefine.h"

//using TinyCC::msg;

CTinyTCPIF::CTinyTCPIF(void)
: m_ServerPort(0),m_ServerMsgThread(NULL)
{
	m_pMsgFunctor = NULL;
	m_hRecHandle = NULL;
	g_TimerPool.requestTimer(this,m_ServerConnTimer,&CTinyTCPIF::processTimer,5000,true);
	//start server msg process func
	m_ServerMsgThread = new CTinyThread(this,&CTinyTCPIF::serverMsgFunc,(void*)this);
}

CTinyTCPIF::~CTinyTCPIF(void)
{
	g_TimerPool.returnTimer(m_ServerConnTimer);
}

bool CTinyTCPIF::sendMsg(int socketID,CTinyMsg& msg)
{
	//if server connection
	if(socketID == m_serverConn.getSocketId())
	{
		return true;
	}
	
	//if not tcpserver too
	if(m_TCPServer->isConnected(socketID) == false)
		return false;

	//if tcpserver msg
	long length;
	TinyCC::msg::CTinyTCPMsg tinyTCPMsg;
	const char * data = tinyTCPMsg.package(length,&msg);

	if(length>0)
	{
		m_TCPServer->sendData(socketID,(void*)data,length);
		return true;
	}
	else
		return false;
}

void CTinyTCPIF::processTimer(std::string timerID)
{
	if(m_ServerConnTimer == timerID)
	{
		//check serverConnection
		if(checkServerConn() == false)
		{
			this->connectToServer();
		}
			
	}
}

bool CTinyTCPIF::sendServerMsg(CTinyMsg& msg)
{
	//if(checkServerConn() == false)
	//	return false;

	msg.setSourceIP(m_LocalIP.c_str());
	msg.setSourcePort(m_localPort);

	g_Logger.log(debug1,msg);

	long length;
	TinyCC::msg::CTinyTCPMsg tinyTCPMsg;
	const char * data = tinyTCPMsg.package(length,&msg);

	if(length>0)
	{
		m_serverConn.sendData((void*)data,length);
		return true;
	}
	else
		return false;
}

bool CTinyTCPIF::checkServerConn(void)
{
	return  m_serverConn.getIsConnected();
}

void CTinyTCPIF::serverMsgFunc(void* param)
{
	CTinyTCPIF* pServerClient = (CTinyTCPIF*)param;

	if(param == NULL)
		return ;
	
	TinyCC::msg::CTinyTCPRawMsg* rawMsg = NULL;
	TinyCC::msg::CTinyTCPMsg tcpmsg;
	TinyCC::msg::CTinyMsg inMsg,outMsg;

	while(true)
	{
		if(m_hRecHandle == NULL)
		{
			Sleep(2000);
			continue;
		}
		switch(WaitForSingleObject(m_hRecHandle,200))
		{
		case WAIT_OBJECT_0:
			{
				ResetEvent( m_hRecHandle );
				while(true)
				{
					rawMsg = pServerClient->m_serverConn.getNextMsg();
					if( rawMsg != NULL )
					{
						//process msg
						inMsg.clear();
						if(tcpmsg.unPackage(*rawMsg,&inMsg))
						{
							if(pServerClient->m_pMsgFunctor!= NULL)
								(*pServerClient->m_pMsgFunctor)(inMsg,outMsg);
							if(outMsg.getMsgIndex() != 0&& outMsg.getMsgItem() != 0)
							{
								//send msg automatic
								pServerClient->sendServerMsg(outMsg);
							}
						}
						else
							inMsg.clear();//msg not right, clear data
					}
					else  //msg empty, break the while
					{
						ResetEvent( m_hRecHandle );
						break;
					}
				}
			}break;
		default:
			break;
		}
	}
}

bool CTinyTCPIF::connectToServer(void)
{
	m_LocalIP = g_Config.getConfig()->m_ModuleIP;
	m_localPort = g_Config.getConfig()->m_ModulePort;
	m_hRecHandle = CreateEvent(NULL,true,false,NULL); 
	if(m_serverConn.connectToServer(m_ServerIP.c_str(),m_ServerPort,m_hRecHandle) == false)
	{
		ResetEvent(m_hRecHandle);
		CloseHandle(m_hRecHandle);
		m_hRecHandle = NULL;
		return false;
	}
	else
		return true;
}


void CTinyTCPIF::RaiseAlertEvt(string deviceID,string deviceType)
{
	CTinyMsg msg;
	msg.setMsgIndex(VOICECARD_ACTION);
	msg.setMsgItem(VOICECARD_ALERT);
	msg.setDefaultParam(VOICECARD_ALERT_MODULENAME,g_Config.getConfig()->m_InstanceName);
	msg.setDefaultParam(VOICECARD_ALERT_DEVICEID,deviceID);
	msg.setDefaultParam(VOICECARD_ALERT_DEVICETYPE,deviceType);
	this->sendServerMsg(msg);
}

void CTinyTCPIF::RaiseConnectedEvt(string deviceID,string deviceType)
{
	CTinyMsg msg;
	msg.setMsgIndex(VOICECARD_ACTION);
	msg.setMsgItem(VOICECARD_ALERT);
	msg.setDefaultParam(VOICECARD_ALERT_MODULENAME,g_Config.getConfig()->m_InstanceName);
	msg.setDefaultParam(VOICECARD_ALERT_DEVICEID,deviceID);
	msg.setDefaultParam(VOICECARD_ALERT_DEVICETYPE,deviceType);
	this->sendServerMsg(msg);
}